package com.cskaoyan.javase.oop3._0abstract._3exercise;

import com.sun.org.apache.bcel.internal.classfile.Code;

/**
 * 公司正在开发一套员工管理系统，需要对公司内部存在的员工进行管理
 * 公司将员工分为三类，普通员工负责杂项工作，程序员负责技术开发，经理负责统筹规划
 * 普通员工包含3个属性：姓名、工号以及工资，行为是工作
 * 程序员包含3个属性：姓名、工号以及工资，行为是工作和加班（overtime work）
 * 经理包含4个属性：姓名、工号、工资以及奖金（bonus），行为是工作
 *
 * 请使用所学的知识设计该员工系统
 *
 * 首先很明显需要一个父类,来进行成员的复用,那么谁应该用来做父类呢?
 * 如果只从成员复用的角度,普通员工包含了所有员工的成员(变量和方法),用它来做复用成员的父类是可以的,但是:
 *      1.长远的角度来说,普通员工是真实存在于员工系统中,如果后续有修改的需求,那这修改就会体现到所有员工上
 *          这肯定是不合适的
 *      2.从实际开发角度出现,每一个员工都必须要"工作",这时使用抽象方法来制定"标准和规范""占位"是一个更好的选择
 *          所以我们需要一个不存在于系统中的,一个抽象父类,抽象的员工类.
 *
 * 要求类中提供必要的方法进行属性访问（description）
 * 打印属性的方法,程序员类和普通员工类可以共用一个方法,所以可以把这个方法写在抽象父类中.
 *
 *
 * @since 17:16
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        AbstractStaff as;
        as = new GeneralStaff("张三", 1, 20000);
        as.work();
        as.printStaff();
        as = new Coder("李四", 2, 40000);
        as.work();
        if (as instanceof Coder) {
            Coder c = (Coder) as;
            c.overtimeWork();
        }
        as.printStaff();
        as = new Manager("麻子", 3, 50000, 100000);
        as.work();
        if (as instanceof Manager) {
            Manager m = (Manager) as;
            System.out.println(m.getBonus());
        }
        as.printStaff();
    }
}

abstract class AbstractStaff {
    String name;
    int id;
    double salary;

    public AbstractStaff(String name, int id, double salary) {
        this.name = name;
        this.id = id;
        this.salary = salary;
    }

    // 工作要声明为抽象方法
    public abstract void work();

    // 打印员工
    public void printStaff() {
        System.out.println("该员工的名字是" + name + ",他的工号是" + id + ",他的工资是" + salary);
    }
}

// 具体员工类
// 普通员工类
class GeneralStaff extends AbstractStaff {
    public GeneralStaff(String name, int id, double salary) {
        super(name, id, salary);
    }

    @Override
    public void work() {
        System.out.println("负责杂项工作!");
    }
}

// 程序员类
class Coder extends AbstractStaff {
    public Coder(String name, int id, double salary) {
        super(name, id, salary);
    }

    public void overtimeWork() {
        System.out.println("007");
    }

    @Override
    public void work() {
        System.out.println("负责技术开发!");
    }
}

// 经理类
class Manager extends AbstractStaff {
    private double bonus;

    @Override
    public void printStaff() {
        System.out.println("该员工的名字是" + name + ",他的工号是" + id + ",他的工资是" + (salary + bonus));
    }

    public double getBonus() {
        return bonus;
    }

    public Manager(String name, int id, double salary, double bonus) {
        super(name, id, salary);
        this.bonus = bonus;
    }

    @Override
    public void work() {
        System.out.println("负责统筹规划");
    }
}